home *** CD-ROM | disk | FTP | other *** search
/ Info-Mac 3 / Info_Mac_1994-01.iso / Development / Source / MultiSession 1.04 Source / Core 27⁄June⁄1993 / CArray.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-05-18  |  10.1 KB  |  393 lines  |  [TEXT/KAHL]

  1. /* CArray.c */
  2.  
  3. #include "CArray.h"
  4. #include "Memory.h"
  5.  
  6.  
  7. /* */                CArray::CArray()
  8.     {
  9.         ArrayType**        Temp;
  10.  
  11.         Temp = (ArrayType**)AllocHandle(sizeof(ArrayType));
  12.         FirstBlock = Temp;
  13.         (**Temp).Next = NIL;
  14.         (**Temp).NumElements = 0;
  15.     }
  16.  
  17.  
  18. /* */                CArray::~CArray()
  19.     {
  20.         ArrayType**        Scan;
  21.  
  22.         while (FirstBlock != NIL)
  23.             {
  24.                 Scan = FirstBlock;
  25.                 FirstBlock = (**FirstBlock).Next;
  26.                 ReleaseHandle((Handle)Scan);
  27.             }
  28.     }
  29.  
  30.  
  31. void                CArray::IArray(long TheBytesPerElement, long TheElementsPerArray)
  32.     {
  33.         BytesPerElement = TheBytesPerElement;
  34.         ElementsPerArray = TheElementsPerArray;
  35.         EXECUTE(ElementsPerArray = 4;)
  36.     }
  37.  
  38.  
  39. long                CArray::GetNumElements(void)
  40.     {
  41.         long                    Count;
  42.         ArrayType**        Scan;
  43.  
  44.         Count = 0;
  45.         Scan = FirstBlock;
  46.         while (Scan != NIL)
  47.             {
  48.                 Count += (**Scan).NumElements;
  49.                 Scan = (**Scan).Next;
  50.             }
  51.         return Count;
  52.     }
  53.  
  54.  
  55. long                CArray::AppendElement(void)
  56.     {
  57.         ArrayType**        Scan;
  58.         ArrayType**        Temp;
  59.         ArrayType**        Lag;
  60.         ArrayType**        Lag2;
  61.         long                    Index;
  62.  
  63.         Scan = FirstBlock;
  64.         Index = 0;
  65.         Lag = NIL;
  66.         Lag2 = NIL;
  67.         do
  68.             {
  69.                 Index += (**Scan).NumElements;
  70.                 Lag2 = Lag;
  71.                 Lag = Scan;
  72.                 Scan = (**Scan).Next;
  73.             } while (Scan != NIL);
  74.         if ((**Lag).NumElements >= ElementsPerArray)
  75.             {
  76.                 /* adding whole new block on the end */
  77.                 Temp = (ArrayType**)AllocHandle(sizeof(ArrayType) + BytesPerElement);
  78.                 (**Temp).Next = NIL;
  79.                 (**Temp).NumElements = 1;
  80.                 (**Lag).Next = Temp;
  81.                 return Index;
  82.             }
  83.          else
  84.             {
  85.                 /* appending to end of last block */
  86.                 Temp = (ArrayType**)AllocHandle(HandleSize((Handle)Lag) + BytesPerElement);
  87.                 (**Temp).Next = (**Lag).Next;
  88.                 (**Temp).NumElements = (**Lag).NumElements + 1;
  89.                 HRNGCHK(Temp,&((**Temp).Data),BytesPerElement * (**Lag).NumElements);
  90.                 MemCpy((**Temp).Data,(**Lag).Data,BytesPerElement * (**Lag).NumElements);
  91.                 ReleaseHandle((Handle)Lag);
  92.                 if (Lag2 == NIL)
  93.                     {
  94.                         FirstBlock = Temp;
  95.                     }
  96.                  else
  97.                     {
  98.                         (**Lag2).Next = Temp;
  99.                     }
  100.                 return Index;
  101.             }
  102.     }
  103.  
  104.  
  105. long                CArray::InsertElement(long IndexToInsertBefore)
  106.     {
  107.         long                IndexOfFirst;
  108.         long                IndexAfterLast;
  109.         ArrayType**    Scan;
  110.         ArrayType**    Lag;
  111.         ArrayType**    Temp;
  112.  
  113.      RetryPoint:
  114.         Scan = FirstBlock;
  115.         IndexOfFirst = 0;
  116.         Lag = NIL;
  117.      RepeatPoint:
  118.         IndexAfterLast = IndexOfFirst + (**Scan).NumElements;
  119.         if ((IndexToInsertBefore >= IndexOfFirst)
  120.             && (IndexToInsertBefore < IndexAfterLast))
  121.             {
  122.                 if ((**Scan).NumElements >= ElementsPerArray)
  123.                     {
  124.                         ArrayType**        FirstHalf;
  125.                         ArrayType**        SecondHalf;
  126.                         long                    ElementsInFirstHalf;
  127.                         long                    ElementsInSecondHalf;
  128.                         long                    nScan;
  129.  
  130.                         ElementsInFirstHalf = (**Scan).NumElements / 2;
  131.                         ElementsInSecondHalf = (**Scan).NumElements - ElementsInFirstHalf;
  132.                         FirstHalf = (ArrayType**)AllocHandle(sizeof(ArrayType)
  133.                             + (ElementsInFirstHalf * BytesPerElement));
  134.                         SecondHalf = (ArrayType**)AllocHandle(sizeof(ArrayType)
  135.                             + (ElementsInSecondHalf * BytesPerElement));
  136.                         if (Lag == NIL)
  137.                             {
  138.                                 FirstBlock = FirstHalf;
  139.                             }
  140.                          else
  141.                             {
  142.                                 (**Lag).Next = FirstHalf;
  143.                             }
  144.                         (**FirstHalf).Next = SecondHalf;
  145.                         (**FirstHalf).NumElements = ElementsInFirstHalf;
  146.                         (**SecondHalf).Next = (**Scan).Next;
  147.                         (**SecondHalf).NumElements = ElementsInSecondHalf;
  148.                         HRNGCHK(FirstHalf,&((**FirstHalf).Data[0]),
  149.                             BytesPerElement * (**FirstHalf).NumElements);
  150.                         HRNGCHK(Scan,&((**Scan).Data[0]),
  151.                             BytesPerElement * (**FirstHalf).NumElements);
  152.                         MemCpy(&((**FirstHalf).Data[0]),&((**Scan).Data[0]),
  153.                             BytesPerElement * (**FirstHalf).NumElements);
  154.                         HRNGCHK(SecondHalf,&((**SecondHalf).Data[0]),
  155.                             BytesPerElement * (**SecondHalf).NumElements);
  156.                         HRNGCHK(Scan,&((**Scan).Data[
  157.                             BytesPerElement * (**FirstHalf).NumElements]),
  158.                             BytesPerElement * (**SecondHalf).NumElements);
  159.                         MemCpy(&((**SecondHalf).Data[0]),&((**Scan).Data[
  160.                             BytesPerElement * (**FirstHalf).NumElements]),
  161.                             BytesPerElement * (**SecondHalf).NumElements);
  162.                         ReleaseHandle((Handle)Scan);
  163.                         /* go back and make sure we are still inserting into proper block */
  164.                         goto RetryPoint;
  165.                     }
  166.                  else
  167.                     {
  168.                         long                Reference;
  169.  
  170.                         /* opening hole in block */
  171.                         /* Now we have the block (Scan) so where to insert into it? */
  172.                         Reference = IndexToInsertBefore - IndexOfFirst;
  173.                         /* insert into relative position of <Reference>. */
  174.                         Temp = (ArrayType**)AllocHandle(HandleSize((Handle)Scan) + BytesPerElement);
  175.                         (**Temp).Next = (**Scan).Next;
  176.                         (**Temp).NumElements = (**Scan).NumElements + 1;
  177.                         if (Lag == NIL)
  178.                             {
  179.                                 FirstBlock = Temp;
  180.                             }
  181.                          else
  182.                             {
  183.                                 (**Lag).Next = Temp;
  184.                             }
  185.                         /* copying over preceding zone */
  186.                         HRNGCHK(Temp,&((**Temp).Data[0]),Reference * BytesPerElement);
  187.                         HRNGCHK(Scan,&((**Scan).Data[0]),Reference * BytesPerElement);
  188.                         MemCpy(&((**Temp).Data[0]),&((**Scan).Data[0]),Reference * BytesPerElement);
  189.                         /* copying over element (there isn't one so nothing really happens.) */
  190.                         HRNGCHK(Temp,&((**Temp).Data[Reference * BytesPerElement]),BytesPerElement);
  191.                         /* MemCpy(&((**Temp).Data[Reference * BytesPerElement]),
  192.                             Element,BytesPerElement); */
  193.                         /* copying over succeeding range */
  194.                         HRNGCHK(Temp,&((**Temp).Data[(Reference * BytesPerElement)
  195.                             + BytesPerElement]),(BytesPerElement * (**Scan).NumElements)
  196.                             - (Reference * BytesPerElement));
  197.                         HRNGCHK(Scan,&((**Scan).Data[Reference * BytesPerElement]),
  198.                             (BytesPerElement * (**Scan).NumElements) - (Reference * BytesPerElement));
  199.                         MemCpy(&((**Temp).Data[(Reference * BytesPerElement) + BytesPerElement]),
  200.                             &((**Scan).Data[Reference * BytesPerElement]),
  201.                             (BytesPerElement * (**Scan).NumElements) - (Reference * BytesPerElement));
  202.                         ReleaseHandle((Handle)Scan);
  203.                     }
  204.                 return IndexToInsertBefore;
  205.             }
  206.         IndexOfFirst = IndexAfterLast;
  207.         if ((**Scan).Next == NIL)
  208.             {
  209.                 /* oops, we ran off end.  call AppendElement */
  210.                 return AppendElement();
  211.             }
  212.         Lag = Scan;
  213.         Scan = (**Scan).Next;
  214.         goto RepeatPoint;
  215.     }
  216.  
  217.  
  218. MyBoolean        CArray::DeleteElement(long TheOneToDelete)
  219.     {
  220.         long                IndexOfFirst;
  221.         long                IndexAfterLast;
  222.         long                IndexToDelete;
  223.         ArrayType**    Scan;
  224.         ArrayType**    Lag;
  225.         ArrayType**    Temp;
  226.  
  227.      RetryPoint:
  228.         Scan = FirstBlock;
  229.         IndexOfFirst = 0;
  230.         Lag = NIL;
  231.      RepeatPoint:
  232.         IndexAfterLast = IndexOfFirst + (**Scan).NumElements;
  233.         if ((TheOneToDelete >= IndexOfFirst)
  234.             && (TheOneToDelete < IndexAfterLast))
  235.             {
  236.                 IndexToDelete = TheOneToDelete - IndexOfFirst;
  237.                 Temp = (ArrayType**)AllocHandle(((**Scan).NumElements - 1) * BytesPerElement
  238.                     + sizeof(ArrayType));
  239.                 (**Temp).Next = (**Scan).Next;
  240.                 (**Temp).NumElements = (**Scan).NumElements - 1;
  241.                 HRNGCHK(Temp,&((**Temp).Data[0]),IndexToDelete * BytesPerElement);
  242.                 HRNGCHK(Scan,&((**Scan).Data[0]),IndexToDelete * BytesPerElement);
  243.                 MemCpy(&((**Temp).Data[0]),&((**Scan).Data[0]),IndexToDelete * BytesPerElement);
  244.                 HRNGCHK(Temp,&((**Temp).Data[IndexToDelete * BytesPerElement]),
  245.                     ((**Scan).NumElements - 1) * BytesPerElement - IndexToDelete * BytesPerElement);
  246.                 HRNGCHK(Scan,&((**Scan).Data[IndexToDelete * BytesPerElement + BytesPerElement]),
  247.                     ((**Scan).NumElements - 1) * BytesPerElement - IndexToDelete * BytesPerElement);
  248.                 MemCpy(&((**Temp).Data[IndexToDelete * BytesPerElement]),
  249.                     &((**Scan).Data[IndexToDelete * BytesPerElement
  250.                     + BytesPerElement]),((**Scan).NumElements - 1) * BytesPerElement
  251.                     - IndexToDelete * BytesPerElement);
  252.                 if (Lag == NIL)
  253.                     {
  254.                         FirstBlock = Temp;
  255.                     }
  256.                  else
  257.                     {
  258.                         CheckHandleExistence((Handle)Lag);
  259.                         (**Lag).Next = Temp;
  260.                     }
  261.                 ReleaseHandle((Handle)Scan);
  262.                 if (((**Temp).NumElements == 0) && (Temp != FirstBlock))
  263.                     {
  264.                         (**Lag).Next = (**Temp).Next;
  265.                         ReleaseHandle((Handle)Temp);
  266.                         Temp = (**Lag).Next;
  267.                     }
  268.                 return True;
  269.             }
  270.         IndexOfFirst = IndexAfterLast;
  271.         if ((**Scan).Next == NIL)
  272.             {
  273.                 return False;
  274.             }
  275.         Lag = Scan;
  276.         Scan = (**Scan).Next;
  277.         goto RepeatPoint;
  278.     }
  279.  
  280.  
  281. MyBoolean        CArray::GetElement(long Index, void* PlaceToPut)
  282.     {
  283.         long                IndexOfFirst;
  284.         long                IndexAfterLast;
  285.         ArrayType**    Scan;
  286.         ArrayType**    Lag;
  287.         ArrayType**    Temp;
  288.  
  289.         StackSizeTest();
  290.         Scan = FirstBlock;
  291.         IndexOfFirst = 0;
  292.         Lag = NIL;
  293.      RepeatPoint:
  294.         IndexAfterLast = IndexOfFirst + (**Scan).NumElements;
  295.         if ((Index >= IndexOfFirst)
  296.             && (Index < IndexAfterLast))
  297.             {
  298.                 MemCpy(PlaceToPut,&((**Scan).Data[(Index - IndexOfFirst) * BytesPerElement]),
  299.                     BytesPerElement);
  300.                 return True;
  301.             }
  302.         IndexOfFirst = IndexAfterLast;
  303.         if ((**Scan).Next == NIL)
  304.             {
  305.                 return False;
  306.             }
  307.         Lag = Scan;
  308.         Scan = (**Scan).Next;
  309.         goto RepeatPoint;
  310.     }
  311.  
  312.  
  313. MyBoolean        CArray::PutElement(long Index, void* PlaceToGet)
  314.     {
  315.         long                IndexOfFirst;
  316.         long                IndexAfterLast;
  317.         ArrayType**    Scan;
  318.         ArrayType**    Lag;
  319.         ArrayType**    Temp;
  320.  
  321.         Scan = FirstBlock;
  322.         IndexOfFirst = 0;
  323.         Lag = NIL;
  324.      RepeatPoint:
  325.         IndexAfterLast = IndexOfFirst + (**Scan).NumElements;
  326.         if ((Index >= IndexOfFirst)
  327.             && (Index < IndexAfterLast))
  328.             {
  329.                 MemCpy(&((**Scan).Data[(Index - IndexOfFirst) * BytesPerElement]),
  330.                     PlaceToGet,BytesPerElement);
  331.                 return True;
  332.             }
  333.         IndexOfFirst = IndexAfterLast;
  334.         if ((**Scan).Next == NIL)
  335.             {
  336.                 return False;
  337.             }
  338.         Lag = Scan;
  339.         Scan = (**Scan).Next;
  340.         goto RepeatPoint;
  341.     }
  342.  
  343.  
  344. void*                CArray::GetElementAddress(long Index)
  345.     {
  346.         long                IndexOfFirst;
  347.         long                IndexAfterLast;
  348.         ArrayType**    Scan;
  349.         ArrayType**    Lag;
  350.         ArrayType**    Temp;
  351.  
  352.         Scan = FirstBlock;
  353.         IndexOfFirst = 0;
  354.         Lag = NIL;
  355.      RepeatPoint:
  356.         IndexAfterLast = IndexOfFirst + (**Scan).NumElements;
  357.         if ((Index >= IndexOfFirst)
  358.             && (Index < IndexAfterLast))
  359.             {
  360.                 return &((**Scan).Data[(Index - IndexOfFirst) * BytesPerElement]);
  361.             }
  362.         IndexOfFirst = IndexAfterLast;
  363.         if ((**Scan).Next == NIL)
  364.             {
  365.                 return NIL;
  366.             }
  367.         Lag = Scan;
  368.         Scan = (**Scan).Next;
  369.         goto RepeatPoint;
  370.     }
  371.  
  372.  
  373. MyBoolean        CArray::KillElement(void* Element)
  374.     {
  375.         long            NumThings;
  376.         long            Scan;
  377.         void*            Address;
  378.  
  379.         NumThings = GetNumElements();
  380.         Scan = 0;
  381.         while (Scan < NumThings)
  382.             {
  383.                 Address = GetElementAddress(Scan);
  384.                 if (MemEqu(Element,Address,BytesPerElement))
  385.                     {
  386.                         DeleteElement(Scan);
  387.                         return True;
  388.                     }
  389.                 Scan += 1;
  390.             }
  391.         return False;
  392.     }
  393.